﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace 电梯调度程序第一阶段算法CS
{
    class Elevator
    {
        public static int amount = 2;
        public static int flooramount = 8;//0层代表-1楼
        int id, position,direction, weight, maxweight, speed, maxspeed;
        int destination = -1;
        static public int[] floor = new int[flooramount+1];
        DestList destlist;
        static public Elevator[] elevator = new Elevator[2];
        static Task elevatorthread = new Task(postthread);
        static public Task inputdestinationthread = new Task(Elevator.inputdestination);
        public void AddDestination(int i)
        {
            if (!destlist.Contains(i)&&i>=0&&i<=flooramount)
                destlist.Add(i);
        }
        public Elevator(int i)
        {
            int temp=-1;
            id = i;
            Console.Write("请输入电梯" + i + "的位置：");
            while (temp < 0 || temp > flooramount)
                temp = int.Parse(Console.ReadKey(true).KeyChar.ToString());
            position = temp;
            direction = 0;
            destlist = new DestList(position, direction);
            Console.Write(Position + "\n");
        }
        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        public int Position
        {
            get { return position; }
            set { position = value; }
        }
        public int Direction
        {
            get { return direction; }
            set { direction = value; }
        }
        public int Weight
        {
            get { return weight; }
            set { weight = value; }
        }
        public int Maxweight
        {
            get { return maxweight; }
            set { maxweight = value; }
        }
        public int Speed
        {
            get { return speed; }
            set { speed = value; }
        }
        public int Maxspeed
        {
            get { return maxspeed; }
            set { maxspeed = value; }
        }
        public int Destination
        {
            get { return destination; }
            set { destination = value; }
        }
        public void run()
        {
            Destination = nextpos();
            if (destination == position)
                destination = -1;
            if (destination == -1)
            {
                arrived();
                return;
            }
            else if (destination > position)
            {
                direction = 1;
                position += 1;
            }
            else
            {
                direction = -1;
                position -= 1;
            }
            if (Position == 0)
                Direction = 1;
            else if (Position == flooramount)
                Direction = -1;
            Console.WriteLine("电梯"+id+"到达："+Position+"，当前目的地："+ destination+"，方向为"+ direction);
            
        }
        static public async void postthread()
        {
            while (true)
            {
                elevator[0].run();
                elevator[1].run();
                await Task.Delay(100);
            }
        }
        int relativeState(int dest)
        {
            if (floor[dest] == Direction)
            {
                if (Direction * (dest - Position) > 0)
                    return 0;
                else
                    return 2;
            }
            else
                return 1;
        }
        bool isBestState(int dest)
        {
            int state = relativeState(dest);
            for (int i = 0; i < amount; i++)
            {
                if (relativeState(dest)<state)
                    return false;
            }
            return true;
        }
        bool isNearest(int dest)
        {
            int distance = Math.Abs(dest - Position);
            for (int i = 0; i < amount; i++)
            {
                if (Math.Abs(elevator[i].Position - dest) > distance)
                    return false;
            }
            return true;
        }
        bool isDestination(int dest)
        {
            int distance = Math.Abs(Position - dest);
            for(int i=0;i<amount; i++)
            {
                if(elevator[i].Destination==-1&& Math.Abs(elevator[i].Position - dest) < distance)
                {
                    return false;
                }
                if (elevator[i].Destination == dest)
                {
                    if (Math.Abs(dest - Position) > Math.Abs(dest - elevator[i].Position))
                        return false;
                    else if(relativeState(dest)<elevator[i].relativeState(dest))
                        return true;
                }
            }
            return true;
        }
        public void arrived()
        {
            if (destlist.Contains(Position) || floor[Position] == Direction)
            {
                if (destlist.Contains(Position))
                    destlist.Remove(Position);
                if (floor[Position] == Direction)
                    floor[Position] = 0;
                Console.WriteLine("电梯"+id+"已到达：" + Position);
            }
        }
        public int nextpos()
        {
            if(Direction==0)
            {
                int distance = flooramount, nearest = 0;
                for (int i= 0; i< flooramount; i++)
                {
                    if ((floor[i] != 0 || destlist.Contains(i)) && Math.Abs(i - Position) < distance)
                        nearest = i;
                }
                if (nearest <= Position)
                    Direction = -1;
                else
                    Direction = 1;
            }
            destlist.Currentposition = Position;
            destlist.Currentdirection = Direction;
            if (floor[Position] == Direction || destlist.Contains(Position))
                return Position;
            for (int i=0; i<2* (flooramount+1);i++)
            {
                if (Position == 0)
                    Direction = 1;
                else if (Position == flooramount)
                    Direction = -1;
                int currentposition = destlist.next();
                if (floor[currentposition] == destlist.Currentdirection && isDestination(currentposition))
                {
                    return currentposition;
                }
                if (destlist.Contains(currentposition))
                    return currentposition;
            }
            return -1;
        }
        static public void elevatorstarter()
        {
            for (int i = 0; i < Elevator.amount; i++)
            {
                elevator[i] = new Elevator(i);
            }
            elevator[0].AddDestination(4);
            elevator[0].AddDestination(1);
            elevator[0].AddDestination(2);
            elevator[0].AddDestination(3);
            elevator[0].AddDestination(4);
            elevator[0].AddDestination(5);
            elevator[0].AddDestination(6);
            elevator[0].AddDestination(7);
            elevator[0].AddDestination(8);
            Elevator.floor[3] = 1;
            Elevator.floor[1] = 1;
            Elevator.floor[2] = 1;
            Elevator.floor[3] = 1;
            Elevator.floor[4] = 1;
            Elevator.floor[5] = 1;
            Elevator.floor[6] = 1;
            Elevator.floor[7] = -1;
            Elevator.floor[6] = -1;
            elevatorthread.Start();
            Elevator.inputdestinationthread.Start();
            Elevator.inputdestinationthread.Wait();
        }
        static public void inputdestination()
        {
            while (true)
            {
                try
                {
                    elevator[0].AddDestination(int.Parse(Console.ReadKey(true).KeyChar.ToString()));
                }
                catch
                {

                }
            }
        }
    }
}
